// OGoMojo
// Whitemice.MOGI.RPC2.Document
// License: LGPL
// Copyright: Whitemice Consulting, 2006
// Author(s): Adam Tauno Williams (awilliam@whitemice.org)
using System;
using System.Collections;
using Whitemice.MOGI;
using CookComputing.XmlRpc;

namespace Whitemice.MOGI.RPC2 
{
	/// \brief Implementation of IDocument
	public abstract class Document : Whitemice.MOGI.Document, IDocument 
	{
		//internal	XmlRpcStruct document;
		internal 	XmlRpcStruct	document;
		protected	Whitemice.MOGI.RPC2.Server server;
		//protected	DocumentType 	type;
		protected	bool 			modified;
		protected	ArrayList 		extendedAttributeList;
		protected	string			documentId;
		
		/// \brief Constructor
		/// \param document An XmlRpcStruct document
		/// \param server Reference to server object			
		public Document(XmlRpcStruct document, Whitemice.MOGI.RPC2.Server server) : base((IServer) server)
		{
			if (document == null)
				document = new XmlRpcStruct();
				else this.document = document;
			this.server = server;
			this.extendedAttributeList = new ArrayList();
			if (Extended)
			{
				foreach(string attribute in (string[])document["extendedKeys"])
					extendedAttributeList.Add(attribute);
			}
		}
		
		public Document(string documentId, Whitemice.MOGI.RPC2.Server server) : base((IServer) server)
		{
			document = new XmlRpcStruct();
			this.documentId = documentId;
			this.server = server;
			this.extendedAttributeList = new ArrayList();			
		}
		
		/// \brief Provides the company number
		/// \note This value is derived from the id attribute		
		public virtual string Number 
		{ 
			get 
			{
				if(this.document.ContainsKey("id"))
				{
					string id = (string)this.document["id"];
					Log.Debug("Number == " + (id.Substring(id.LastIndexOf('/') + 1)));
					return id.Substring(id.LastIndexOf('/') + 1);
				}
				Log.Debug("Number == 0");
				return "0";
			}
		}		

		/// \brief Returns the unique name of the object		
		/*
		public abstract string Name 
		{
			get;
		}
		*/

		/// \brief Accessor for the objectVersion value
		public virtual int Version 
		{
			get
			{
				Log.Debug("Version == ");
				if (document.Contains("objectVersion"))
					return (int)this.document["objectVersion"];
				return 0;
		 	}
		 }
		 
		 /// \brief Get short numeric id from full OGo/Skyrix Id
		 /// \param skyrixId A full Skyrix style id to be parsed down to primary key
		 /// \note OpenGroupware returns lots of things like:
		 ///    skyrix://hostname/instanceId/objectId
		 /// in the Id field of documents,  but all the function calls just
		 /// want that last Id part as their parameters,  so this utility
		 /// method turns that skyrix://... Id into a short #### id.
		 protected string ShortId(string skyrixId) 
		 {
		 	Log.Debug("ShortId == " + (skyrixId.Split('/'))[4]);
		 	return (skyrixId.Split('/'))[4];
		 }
		
		/// \brief Indicate if the document has extended attributes
		protected bool Extended 
		{
			get 
			{
				if (document.Contains("extendedKeys")) 
				{
					Log.Debug("Extended == true");
					return true;
				}
				Log.Debug("Extended == false");
				return false;
			}
		}

		/// \brief Indicate if document has the specified attribute
		/// \param attrubute The XML-RPC key into the extended attribute array
		public bool HasExtendedAttribute(string attribute) 
		{
			bool found;
		
			Log.Debug("HasExtendedAttribute(" + attribute + ")");
			found = false;
			if (Extended) 
			{
				foreach(string key in (string[])document["extendedKeys"])
					if (key == attribute) found = true;
			}
			return found;
		}

		/// \brief Return value of specified extended attribute
		/// \param attrubute The XML-RPC key into the extended attribute array
		/// \note Return value must be cast to the appropriate type
		public object ExtendedAttribute(string attribute)
		{
			Log.Debug("ExtendedAttribute(" + attribute + ")");
			if (HasExtendedAttribute(attribute)) 
			{
				if (((XmlRpcStruct)document["extendedAttrs"]).Contains(attribute))
					return ((XmlRpcStruct)document["extendedAttrs"])[attribute];
					else return "";
			} else 
				return null;
		}

		/// \brief Set value of extended attribute
		/// \param attribute
		/// \param value		
		public void ExtendedAttribute(string attribute, object value)
		{
			Log.Debug("HasExtendedAttribute(" + attribute + ", VALUE)");
			if (HasExtendedAttribute(attribute))
			{
				if (((XmlRpcStruct)document["extendedAttrs"]).Contains(attribute))
					((XmlRpcStruct)document["extendedAttrs"])[attribute] = value;
					else
						((XmlRpcStruct)document["extendedAttrs"]).Add(attribute, value);
			}
		}
		
		public new event DocumentModifiedDelegate Modified;
		
		public bool IsModified
		{
			get { return modified; }
		}		
	}
}
